244. 在GCE使用filebeat傳到GKE的ECK
WHY
RD說他要搞一台自動錄影的服務,
本來以為只有一個服務,那就掛在GKE上就好了。
但是,他有兩個服務A跟B,兩邊的資料要互通。
真要用GKE硬作也是可以,但如果這個服務本身效能就吃很大,
那用k8s也是要多開一台機器,那不如就用GCE吧。
然後,問題就來了,LOG咧!?
Log出問題時要查,最好也是傳去共同的ECK上面,但ECK在GKE上面。
Solution
抓取log的流程也跟一般的filebeat差不多。
filebeat會從主機上的 /var/lib/docker/containers/*/*.log
抓取。
這邊文字檔的log是docker logs的資料,也就是程式的stdout。
Docker-compose.yaml
我是用docker compose ,比較好管理。
services:
filebeat:
image: docker.elastic.co/beats/filebeat:8.15.3
build: filebeat
container_name: filebeat
user: root
restart: unless-stopped
environment:
- ELASTICSEARCH_HOSTS=https://10.60.7.192:9200
- ELASTICSEARCH_USERNAME=elastic
- ELASTICSEARCH_PASSWORD=PASSWORD
labels:
co.elastic.logs/enabled: "false"
volumes:
- ./filebeat.yml:/usr/share/filebeat/filebeat.yml
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./ca.crt:/etc/pki/client/ca.crt
- ./tls.crt:/etc/pki/client/cert.pem
- ./tls.key:/etc/pki/client/cert.key
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "2"
networks:
- zlm_network
networks:
zlm_network:
driver: bridge
name: zlm_network
主要會著重於volume的部分。
其他地方可能有點差異會抓幾個講。
General
user: root
不設定的話,在filebeat.yml
的logging 會出現權限不足的錯誤。
- network 的設定,讓他跟要抓取log的服務放在一起,故同一個網路名稱。
Volume
- filebeat.yml的設定檔連結,這部份沒什麼問題。
裡面內容會在下面說。 - 抓取log的路徑
/var/lib/docker/containers
- 掛載SSL憑證
為什麼要掛載呢?因為ECK在安裝的時候,預設都走ssl,
但ECK安裝時在GKE上面,而目前filebeat在GCE,
所以要拿ECK在GKE上面的憑證來用。
重點來了,你怎麼知道要抓哪個憑證來用,
此時我們可以先去看一下GKE的ECK裡面的設定檔。
volumes:
- name: elastic-internal-http-certificates
secret:
secretName: prod-es-http-certs-internal
defaultMode: 420
optional: false
此時,就能去decode secret了
kubectl get secret prod-es-http-certs-internal -n elastic-system -o=jsonpath='{.data.ca\.crt}' | base64 -d;echo
kubectl get secret prod-es-http-certs-internal -n elastic-system -o=jsonpath='{.data.tls\.crt}' | base64 -d;echo
kubectl get secret prod-es-http-certs-internal -n elastic-system -o=jsonpath='{.data.tls\.key}' | base64 -d;echo
之後將key ,掛載讓filebeat能夠讀取即可。
Filebeat.yml
filebeat.inputs:
- type: container
enabled: true
paths:
- '/var/lib/docker/containers/*/*.log'
tags: ["videosokoban-qa"]
processors:
- add_docker_metadata: ~
- drop_event:
when:
not:
equals:
container.name: "zlm-server"
output.elasticsearch:
hosts: https://prod-es-http:9200 #https://10.60.7.192:9200
username: "elastic"
password: "PASSWORD"
ssl:
certificate_authorities:
- "/etc/pki/client/ca.crt"
certificate: "/etc/pki/client/cert.pem"
key: "/etc/pki/client/cert.key"
indices:
- index: "videosokoban-qa-%{+yyyy.MM}"
when.contains:
tags: "videosokoban-qa"
logging:
metrics.enabled: false
level: debug
to_stderr: true
to_files: true
files:
path: /var/log/filebeat
name: filebeat
keepfiles: 7
permissions: 0644
filebeat.input
要擷取的log來源,
已將本機的路徑掛到docker上面的路徑的。
/var/lib/docker/containers/*/*.log
這個路徑擁有所有的docker logs
type 有分成 container與 docker。
據說是docker只能用在docker上面,
但container可以用在任何的容器服務上面。
type: docker
的設定我沒搞出來,有興趣的可以自己試一試。
processors
這邊牽扯到的部分比較多
- add_docker_metadata
增加一些欄位到log裡面,詳細內容可參考 Add Docker metadata - drop_event ,判斷當container_name是 zlm-server的時候,
就不要紀錄,這個值是先塞資料進去到ECK後,再篩選出來的。
條件判斷可參考conditions。
之前還有用過 drop_fileds
,add_cloud_metadata
,
其他更多請參考Define processors
output.elasticsearch
- host & ssl
要將log丟去的ECK伺服器位置。
hosts這邊,本來是用GKE的內部負載平衡的ip位置,
但是直接使用ip位置的話,會出現錯誤。
cannot validate certificate for 10.60.7.192 because it doesn't contain any IP SANs
這是因為伺服器的憑證沒有加過IP地址,
看一下 tls.crt
,裡面的這段。
這裡並沒有ip位置,所以沒辦法通過驗證。
但這個憑證是ECK自動產生的,
所以換個想法,直接讓服務去呼叫 https://prod-es-http:9200
此時,就是到主機設定一下/etc/hosts
,
新增
10.60.7.192 prod-es-http
ref. Secure communication with Elasticsearch
- indices
將特定的tag綁定到指定的indices上
ref.Configure the Elasticsearch output
logging
除錯時,
可以先將to_stderr: true
開啟。
可直接用docker logs filebeat
看 log。
注意,如果要用 to_files
, docker-compose.yaml 記得加上 user: root
,
否則會發生權限不足的情況。
ref. Configure logging
官方的filebeat.yaml ,請參考 filebeat.reference.yml